package com.zktravel.util;

import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.google.common.collect.ImmutableMap;

/**
 * 
 * @author WuBo
 * @date 2016年10月20日
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
public abstract class XmlUtils {
    /**
     * 
     * @param xml
     * @return
     * @throws Exception
     */
    public static Map<String,Object> getMapFromXml(String xml) throws Exception {
    	 Reader reader = new StringReader(xml);
         try {
	        //这里用Dom的方式解析回包的最主要目的是防止API新增回包字段
	    	/*SAXReader xmlReader = new SAXReader();
	        xmlReader.setValidation(false);
	        xmlReader.setEncoding("UTF-8");
	        Document doc = xmlReader.read(xml);
	        */
	        Document doc = DocumentHelper.parseText(xml);
			Element root = doc.getRootElement();
			
	        //获取到document里面的全部结点
	        List<Element> allNodes = root.elements();
	        if (allNodes.isEmpty()) {
	        	return ImmutableMap.of(root.getName(), root.getStringValue());
	        }
        
	        return nodeList2Map(allNodes);
         } finally {
         	reader.close();
         }
    }
    
	private static Map<String, Object> nodeList2Map(List<Element> nodes) {
        Map<String, Object> map = new HashMap<String, Object>();
    	
        for (Element ele : nodes) {
        	List<Element> subNodes = ele.elements();
        	
        	Object obj = null;
        	if (subNodes == null || subNodes.size() == 0) {
        		obj = ele.getData();
        	} else {
        		if (subNodes.size() == 1 && subNodes.get(0).isTextOnly()) { //文本也是子节点
        			obj = ele.getData();
        		} else {
            		obj = nodeList2Map(subNodes);
        		}
        	}
        	
        	if (map.containsKey(ele.getName())) { //节点名已经存在，说明 是一个list
        		Object lastObj = map.get(ele.getName());
        		List<Object> list = null;
        		if (lastObj instanceof List) {
        			list = (List) lastObj;
        		} else {
            		list = new ArrayList<Object>();
            		list.add(lastObj);
            		map.put(ele.getName(), list);
        		}
        		list.add(obj);
        	} else {
            	map.put(ele.getName(), obj);
        	}
        }
    	
        return map;
    }

}
